using System.Text;
using System.Threading.Tasks;
using Abp.Configuration;
using Abp.Web.Models;
using Abp.Zero.Configuration;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using WorkflowCoreDockingDemo.Authorization.Accounts.Dto;
using WorkflowCoreDockingDemo.Authorization.Users;
using WorkflowCoreDockingDemo.Sessions;

namespace WorkflowCoreDockingDemo.Authorization.Accounts
{
    public class AccountAppService : WorkflowCoreDockingDemoAppServiceBase, IAccountAppService
    {
        // from: http://regexlib.com/REDetails.aspx?regexp_id=1923
        public const string PasswordRegex = "(?=^.{8,}$)(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\\s)[0-9a-zA-Z!@#$%^&*()]*$";

        private readonly UserRegistrationManager _userRegistrationManager;
        private readonly ISessionAppService _sessionAppService;
        private readonly IHttpContextAccessor _httpContextAccessor;
        public AccountAppService(
            UserRegistrationManager userRegistrationManager, ISessionAppService sessionAppService, IHttpContextAccessor httpContextAccessor)
        {
            _userRegistrationManager = userRegistrationManager;
            _sessionAppService = sessionAppService;
            _httpContextAccessor = httpContextAccessor;
        }

        public async Task<IsTenantAvailableOutput> IsTenantAvailable(IsTenantAvailableInput input)
        {
            var tenant = await TenantManager.FindByTenancyNameAsync(input.TenancyName);
            if (tenant == null)
            {
                return new IsTenantAvailableOutput(TenantAvailabilityState.NotFound);
            }

            if (!tenant.IsActive)
            {
                return new IsTenantAvailableOutput(TenantAvailabilityState.InActive);
            }

            return new IsTenantAvailableOutput(TenantAvailabilityState.Available, tenant.Id);
        }

        public async Task<RegisterOutput> Register(RegisterInput input)
        {
            var user = await _userRegistrationManager.RegisterAsync(
                input.Name,
                input.Surname,
                input.EmailAddress,
                input.UserName,
                input.Password,
                true // Assumed email address is always confirmed. Change this if you want to implement email confirmation.
            );

            var isEmailConfirmationRequiredForLogin = await SettingManager.GetSettingValueAsync<bool>(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin);

            return new RegisterOutput
            {
                CanLogin = user.IsActive && (user.IsEmailConfirmed || !isEmailConfirmationRequiredForLogin)
            };
        }
        [WrapResult(false)]
        public async Task<WorkflowLoginViewModel> WorkflowLogin()
        {
            var loginInfo = await _sessionAppService.GetCurrentLoginInformations();
            //var context = _httpContextAccessor.HttpContext;
            var result = new WorkflowLoginViewModel
            {
                IsValid = loginInfo.User != null,
                User = new AuthorizationUser
                {
                    IsManager = false,
                    Id = loginInfo.User?.Id.ToString(),
                    Name = loginInfo.User?.Name
                }
            };
            return result;
        }

        public class WorkflowLoginViewModel
        {
            public bool IsValid { get; set; }
            public AuthorizationUser User { get; set; }
        }

        public class AuthorizationUser
        {
            public string Name { get; set; }
            public string Id { get; set; }
            public bool IsManager { get; set; }
        }
    }
}
